/**
 * uni-app统一请求封装
 * 支持多端平台的HTTP请求处理
 */

import { logRequest, error as logError, info as logInfo } from './debug';

// 请求配置接口
interface RequestOptions {
  url: string;
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  data?: any;
  header?: any;
  timeout?: number;
}

// 响应数据接口
interface ResponseData<T = any> {
  code: number;
  message: string;
  data: T;
}

// 基础配置
const BASE_URL = process.env.NODE_ENV === 'development' 
  ? 'http://localhost:3000/api' 
  : 'https://your-api-domain.com/api';

const DEFAULT_TIMEOUT = 10000;

/**
 * 获取当前平台类型
 */
function getPlatformType(): string {
  // #ifdef MP-WEIXIN
  return 'mp-weixin';
  // #endif
  // #ifdef MP-TOUTIAO
  return 'mp-toutiao';
  // #endif
  // #ifdef MP-XHS
  return 'mp-xhs';
  // #endif
  // #ifdef APP-PLUS
  return 'app-plus';
  // #endif
  // #ifdef H5
  return 'h5';
  // #endif
  return 'unknown';
}

/**
 * 统一请求方法
 * @param options 请求配置
 * @returns Promise<ResponseData>
 */
export const request = <T = any>(options: RequestOptions): Promise<ResponseData<T>> => {
  return new Promise((resolve, reject) => {
    // 获取当前平台信息
    const platform = uni.getSystemInfoSync().platform;
    
    // 构建完整URL
    const fullUrl = options.url.startsWith('http') ? options.url : BASE_URL + options.url;
    
    // 获取存储的token
    const token = uni.getStorageSync('token') || '';
    
    // 默认请求头
    const defaultHeader = {
      'Content-Type': 'application/json',
      'Authorization': token ? `Bearer ${token}` : '',
      'Platform': platform,
      'Client-Type': getPlatformType()
    };

    // 合并请求头
    const header = {
      ...defaultHeader,
      ...options.header
    };

    // 发起请求
    uni.request({
      url: fullUrl,
      method: options.method || 'GET',
      data: options.data || {},
      header,
      timeout: options.timeout || DEFAULT_TIMEOUT,
      success: (res: any) => {
        const endTime = Date.now();
        const duration = endTime - (res.startTime || endTime);
        
        logRequest(options.method || 'GET', fullUrl, options.data, res.data, duration);
        logInfo(`请求成功: ${fullUrl}`, { statusCode: res.statusCode, duration });
        
        // 处理HTTP状态码
        if (res.statusCode >= 200 && res.statusCode < 300) {
          const responseData = res.data;
          
          // 处理业务状态码 - 适配后端返回的{success: true}格式
          if (responseData.success === true || responseData.code === 200 || responseData.code === 0) {
            resolve(responseData);
          } else if (responseData.code === 401) {
            // token过期，清除本地存储并跳转登录
            uni.removeStorageSync('token');
            uni.removeStorageSync('userInfo');
            uni.showToast({
              title: '登录已过期，请重新登录',
              icon: 'none'
            });
            // 跳转到登录页
            uni.reLaunch({
              url: '/pages/login/login'
            });
            reject(responseData);
          } else {
            // 其他业务错误
            uni.showToast({
              title: responseData.message || responseData.error || '请求失败',
              icon: 'none'
            });
            reject(responseData);
          }
        } else {
          // HTTP状态码错误
          const errorMsg = `请求失败，状态码：${res.statusCode}`;
          uni.showToast({
            title: errorMsg,
            icon: 'none'
          });
          reject({
            code: res.statusCode,
            message: errorMsg,
            data: null
          });
        }
      },
      fail: (err: any) => {
        const endTime = Date.now();
        const duration = endTime - (err.startTime || endTime);
        
        logError(`请求失败: ${fullUrl}`, err, {
          method: options.method || 'GET',
          data: options.data,
          duration
        });
        
        let errorMessage = '网络请求失败';
        let errorDetails = '';
        
        // 序列化错误对象以便调试
        try {
          errorDetails = JSON.stringify(err, null, 2);
        } catch (e) {
          errorDetails = err.toString();
        }
        
        // 根据错误类型提供更具体的错误信息
        if (err.errMsg) {
          if (err.errMsg.includes('timeout')) {
            errorMessage = '请求超时，请检查网络连接';
          } else if (err.errMsg.includes('fail')) {
            errorMessage = '网络连接失败，请检查网络设置';
          } else if (err.errMsg.includes('abort')) {
            errorMessage = '请求被取消';
          }
        }
        
        uni.showToast({
          title: errorMessage,
          icon: 'none'
        });
        
        reject({
          code: -1,
          message: errorMessage,
          data: null,
          originalError: errorDetails
        });
      }
    });
  });
};

/**
 * GET请求
 * @param url 请求地址
 * @param data 请求参数
 * @param options 其他配置
 */
export const get = <T = any>(url: string, data?: any, options?: Partial<RequestOptions>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    method: 'GET',
    data,
    ...options
  });
};

/**
 * POST请求
 * @param url 请求地址
 * @param data 请求数据
 * @param options 其他配置
 */
export const post = <T = any>(url: string, data?: any, options?: Partial<RequestOptions>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    method: 'POST',
    data,
    ...options
  });
};

/**
 * PUT请求
 * @param url 请求地址
 * @param data 请求数据
 * @param options 其他配置
 */
export const put = <T = any>(url: string, data?: any, options?: Partial<RequestOptions>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    method: 'PUT',
    data,
    ...options
  });
};

/**
 * DELETE请求
 * @param url 请求地址
 * @param data 请求参数
 * @param options 其他配置
 */
export const del = <T = any>(url: string, data?: any, options?: Partial<RequestOptions>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    method: 'DELETE',
    data,
    ...options
  });
};

/**
 * 文件上传
 * @param url 上传地址
 * @param filePath 文件路径
 * @param name 文件对应的key
 * @param formData 其他表单数据
 */
export const uploadFile = (url: string, filePath: string, name: string = 'file', formData?: any): Promise<any> => {
  return new Promise((resolve, reject) => {
    const token = uni.getStorageSync('token') || '';
    const fullUrl = url.startsWith('http') ? url : BASE_URL + url;
    
    uni.uploadFile({
      url: fullUrl,
      filePath,
      name,
      formData: {
        ...formData,
        platform: getPlatformType()
      },
      header: {
        'Authorization': token ? `Bearer ${token}` : ''
      },
      success: (res) => {
        console.log('文件上传成功:', res);
        try {
          const data = JSON.parse(res.data);
          if (data.code === 200 || data.code === 0) {
            resolve(data);
          } else {
            uni.showToast({
              title: data.message || '上传失败',
              icon: 'none'
            });
            reject(data);
          }
        } catch (e: unknown) {
          console.error('上传响应解析失败:', e);
          const errorMessage = e instanceof Error ? e.message : String(e);
          reject({
            code: -1,
            message: '上传响应解析失败',
            data: null,
            originalError: errorMessage
          });
        }
      },
      fail: (err: any) => {
        console.error('文件上传失败:', err);
        const errorMessage = err?.errMsg || err?.message || '文件上传失败';
        
        uni.showToast({
          title: errorMessage,
          icon: 'none'
        });
        reject({
          code: -1,
          message: errorMessage,
          data: err,
          originalError: JSON.stringify(err)
        });
      }
    });
  });
};

// 导出默认请求方法
export default {
  request,
  get,
  post,
  put,
  del,
  uploadFile
};